import mod_ghost,mod_idgen,math
from mod_vector import subtractVectors
import mod_line
import mod_gui
from mod_thing import Thing

class EntityPrototype:
    def __init__(self,glyph,maxHP,startingItemPrototypes=None,blocksBullets=False,blocksVision=False,structural=True):
        self.glyph = glyph
        self.maxHP = maxHP
        self.startingItemPrototypes = startingItemPrototypes
        self.blocksBullets=blocksBullets
        self.blocksVision = blocksVision
        self.structural = structural
        self.deathEffect = None
        self.resistanceMap = {}
        
    def createStartingInventory(self,entity):
        if self.startingItemPrototypes:
            for itemPrototype in self.startingItemPrototypes:
                newItem = itemPrototype.instantiate()
                newItem.setLocation(entity)
    
    def instantiate(self):
        newEntity = Entity(self)
        self.createStartingInventory(newEntity)
        return newEntity

class Entity(Thing):
    def __init__(self,prototype):
        self.items = []
        Thing.__init__(self,prototype)
        
    def die(self):
        if self.items:
            for item in self.items:
                item.setLocation(self.location)
            self.items = []
        oldLocation = self.location
        self.setLocation(None)
        deathEffect = self.deathEffect
        if deathEffect:
            self.deathEffect.doIt(self,oldLocation)
        
    def setHP(self,newHP):
        if newHP > self.maxHP:
            newHP = self.maxHP
        self.HP = newHP
        if newHP <= 0:
            self.die()
    
    def setLocation(self,newLocation):
        oldLocation = self.location
        self.location = newLocation
        oldLevel = None
        newLevel = None
        if oldLocation != None:
            oldLevel,oldCoords = oldLocation
            del oldLevel.entityMap[oldCoords]
        if newLocation != None:
            newLevel,newCoords = newLocation
            if newCoords in newLevel.entityMap:
                otherEntity = newLevel.entityMap[newCoords]
                raise LocationAlreadyOccupiedError((newLocation,otherEntity.glyph))
            newLevel.entityMap[newCoords]=self
        if oldLevel:
            otherLocation = (oldLevel.number,oldCoords)
            oldLevel.propagateGhost(self.generateGhost(),otherLocation)
        else:
            otherLocation = None
        if newLevel and newLevel != oldLevel:
            newLevel.propagateGhost(self.generateGhost(),otherLocation)
    
    def generateGhost(self):
        if self.location:
            level,coords = self.location
            ghostLocation = (level.number,coords)
        else:
            ghostLocation = None
        ghost = mod_ghost.EntityGhost(self.ID,self.prototype,ghostLocation)
        myGlyph = self.__dict__.get('glyph')
        if myGlyph:
            ghost.glyph = myGlyph
        return ghost
    
    def __getattr__(self,name):
        return getattr(self.prototype,name)
        
        
class LocationAlreadyOccupiedError(Exception):
    def __init__(self,value):
        self.value = value
    def __str__(self):
        return repr(self.value)
